/**
 * Copyright 2013-2015. blackdog1987@gmail.com . All rights reserved. 
 */
package com.gmail.blackdog1987.carcare.dao.hibernate;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

/**
 * @author DongGuoChao
 * 
 */
public class HibernateDaoConfigureGenerator {

	private String contextFile;
	private String sourcePath;
	private String sourcePackage;
	private String sessionFactoryName = "sessionFactory";
	private int subStart = 0;

	public HibernateDaoConfigureGenerator() {
	}

	public HibernateDaoConfigureGenerator(String contextFile, String sourcePath, String sourcePackage) {
		this.contextFile = contextFile;
		this.sourcePath = sourcePath;
		this.sourcePackage = sourcePackage;
	}

	public HibernateDaoConfigureGenerator(String contextFile, String sourcePath, String sourcePackage,
			String sessionFactoryName) {
		this.contextFile = contextFile;
		this.sourcePath = sourcePath;
		this.sourcePackage = sourcePackage;
		this.sessionFactoryName = sessionFactoryName;
	}

	public void generate() throws IOException {
		if (this.sourcePackage == null || this.sourcePath == null || this.contextFile == null) {
			throw new NullPointerException("The paramerts sourcePackage,sourcePath,contextFile must not be null.");
		}

		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		dbf.setNamespaceAware(true);
		DocumentBuilder db;
		try {
			db = dbf.newDocumentBuilder();
		} catch (ParserConfigurationException e) {
			throw new RuntimeException(e);
		}

		File file = new File(this.contextFile);
		try {
			Document doc = db.parse(file);
			Element root = (Element) doc.getElementsByTagName("beans").item(0);

			for (String clazz : getDaoClassNames(this.sourcePath)) {
				Element el = doc.createElement("bean");
				String id = clazz.substring(this.subStart, this.subStart + 1).toLowerCase()
						+ clazz.substring(this.subStart + 1);
				el.setAttribute("id", id);
				el.setAttribute("class", this.sourcePackage + "." + clazz);

				Element sf = doc.createElement("property");
				sf.setAttribute("name", "sessionFactory");
				sf.setAttribute("ref", this.sessionFactoryName);

				el.appendChild(sf);
				root.appendChild(el);
			}

			TransformerFactory tFactory = TransformerFactory.newInstance();
			Transformer transformer = tFactory.newTransformer();
			DOMSource source = new DOMSource(doc);
			StreamResult result = new StreamResult(file);
			transformer.transform(source, result);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	protected List<String> getDaoClassNames(String path) {
		List<String> list = new ArrayList<String>();
		File dir = new File(path);
		if (dir.isDirectory()) {
			File[] files = dir.listFiles();
			for (int i = 0; i < files.length; i++) {
				File file = files[i];
				if (!file.isDirectory()) {
					list.add(file.getName().split(".java")[0]);
				}
			}
		}

		return list;
	}

	// ------------------------------------------------------------------------------
	public String getContextFile() {
		return contextFile;
	}

	public void setContextFile(String contextFile) {
		this.contextFile = contextFile;
	}

	public String getSessionFactoryName() {
		return sessionFactoryName;
	}

	public void setSessionFactoryName(String sessionFactoryName) {
		this.sessionFactoryName = sessionFactoryName;
	}

	public String getSourcePath() {
		return sourcePath;
	}

	public void setSourcePath(String sourcePath) {
		this.sourcePath = sourcePath;
	}

	public String getSourcePackage() {
		return sourcePackage;
	}

	public void setSourcePackage(String sourcePackage) {
		this.sourcePackage = sourcePackage;
	}

	public int getSubStart() {
		return subStart;
	}

	public void setSubStart(int subStart) {
		this.subStart = subStart;
	}
	
}
